/**

This file is part of MaCI/GIMnet.

MaCI/GIMnet is free software: you can redistribute it and/or modify it 
under the terms of the GNU Lesser General Public License as published 
by the Free Software Foundation, either version 3 of the License, or 
(at your option) any later version.

MaCI/GIMnet is distributed in the hope that it will be useful, but WITHOUT 
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public 
License for more details.

You should have received a copy of the GNU Lesser General Public 
License along with GIMnet. (See COPYING.LESSER) If not, see 
<http://www.gnu.org/licenses/>.

**/
/**
 *
 * $Id: AudioContainer.hpp,v 1.2 2009-10-20 11:16:06 morsko Exp $
 *
 * \file
 * \brief AudioContainer class handling type conversions and stuff - Header.
 * \author Matthieu Myrsky <matthieu.myrsky@tkk.fi
 * \NOTE: Not ready yet!
 *
 */

#ifndef _MACI_INTERFACES_AUDIO_AUDIOCONTAINER_HPP_
#define _MACI_INTERFACES_AUDIO_AUDIOCONTAINER_HPP_
#include "AudioTypes.hpp"
#include <string>
namespace MaCI {
  namespace Audio {
    /**
     * Container for audio data.
     *
     * This class is a storage class for storing audios in different
     * formats. The CAudioData class of the Audio interface accepts
     * and provides all audio data using this class. This class also
     * implements datatype conversions, so application user shouldn't
     * have to implement conversion routines by hand. All possible
     * conversion combinations are not supported, bu can be if
     * requested. If you need a new conversion, please fill in a 'new
     * feature' report in the project bugtracker.
     *
     * \note To compile this Interface without external dependencies
     * libraries, define compiler macro:
     * 'DISABLE_MACI_AUDIO_AUDIOCONTAINER_EXTERNAL_CONVERSIONS'. This will
     * leave out all external dependencies, but will remove
     * functionality to convert data between formats.
     */
    class CAudioContainer {
    public:
      /** CAudioContainer default constructor.
       *
       */
      CAudioContainer();


      
      
      /** Copy constructor.
       *
       */
      CAudioContainer(const CAudioContainer &aAudioData);


      /**
       * Operator '=' working on non-const object -> Assign.
       */
      CAudioContainer &operator=(CAudioContainer &aAudioData);
      
      
      /**
       * Operator '=' working on const object -> Copy.
       */
      CAudioContainer &operator=(const CAudioContainer &aAudioData);


      /** Destructor.
       */
      ~CAudioContainer();



      /** Store audio in container (with options)
       *
       * This function assigns a databuffer for the container. If the
       * buffer is set to be duplicated, the data is replicated inside
       * the container and no dependencies to the original buffer
       * exist. If the buffer is NOT duplicated, the given pointer /
       * data must remain valid during the lifetime of this object (or
       * until next Reset())
       * 
       * On basic case, this function only requires the three first
       * parameters; data pointer, size and source audio type.
       *
       * This function is also capable of carrying out some basic type
       * conversions. (More may be available in the future if
       * required) If the destination type parameter is set to
       * something else than 'KAudioDataUnknown', the container will
       * attempt to convert data from given sourcetype to destination
       * type.
       * \n
       * For a list of currently supported data conversions, see
       * description of function ConvertTo().
       * \n
       * Conversions with identical source/dest types will
       * always succeed.
       *
       *
       * @param[in] aData       Pointer to source data.
       * @param[in] aSize       Number of bytes of source data available.
       * @return                'true' when the audio was succesfully stored
       *                        using the given parameters. 'false' when
       *                        storing the audio failed. (For example;
       *                        requested conversion is not supported)
       */
      bool SetAudioData(const unsigned char *aData, 
                        const unsigned int aSize,
                        const TAudioInfo aAudioInfo,
                        const EAudioDataType aSrcType,
                        const EAudioDataType aDestType);
                        

      /** Convert current contents of container to another
       * audioformat.
       *
       * This function attempts to convert the data currently inside
       * the container to the specified dataformat. After the data is
       * converted to desired format, contents of the container can be
       * retrieved by calling 'GetAudioDataPtr()' function. Current
       * format parameters of audio can be inspected by calling
       * function 'GetAudioDataType()'.
       * \n
       * Currently supported data conversions are:\n
       * NONE ;) \n
       *
       * \see GetAudioDataPtr
       * \see GetAudioDataSize
       * \see GetAudioDataType
        * \see GetAudioInfoRef
       *
       * @param[in] aDestType   Format to attempt conversion to.
       * @return                'true' when conversion was succesfull,
       *                        'false' when conversion could not be
       *                        done 
       */
      bool ConvertTo(const EAudioDataType aDestType);

      /** Reset container to empty state.
       *
       * This function resets the container to initial empty
       * state. All references to external dataelements are discarded,
       * and internally allocated buffers are freed.
       */
      void Reset(void);
      
      /** Assign function.
       *
       * This claims the ownership for any buffer contained in the
       * source CAudioContainer. This is done by assigning the buffer
       * pointer and invaliding the source element (by marking the
       * source buffer NULL)
       *
       * @param[in] aAudioData Reference to source to assign from.
       */
      void Assign(CAudioContainer &aAudioData);
      

      /** Copy function.
       *
       * This copies the object given as source to current object. Any
       * currently stored buffer is freed or forgotten when
       * approriate.
       *
       * @param[in] aAudioData Reference to source to copy from.
       */
      void Copy(const CAudioContainer &aAudioData);

      /** Return constant reference to AudioInformation structure.
       *
       * \see TAudioInfo
       *
       * @return                Constant reference to TAudioInfo
       *                        structure of this audio.
       */
      inline const TAudioInfo &GetAudioInfoRef(void) const {
        return iAudioInfo;
      }


      /** Return constant pointer to current audio data.
       *
       * This function returns pointer to current audiodata. The data
       * is in the format determined by the current value of
       * 'audiodatatype' field of the TAudioInfo structure (Which can
       * be inspected by calling the 'GetAudioInfoRef()' function) or
       * directly by calling function 'GetAudioDataType()'.
       *
       * \see ConvertTo
       * \see GetAudioDataType
       *
       * @return Constant pointer to current audiodata.
       */
      inline const unsigned char *GetAudioDataPtr(void) const {
        return iAudioDataPtr;
      }

      /** Return size of current audio data and constant pointer to current audio data..
       * 
       * This function returns the number of bytes occupied in the
       * current audio format. The data is in the format determined by
       * the current value of 'audiodatatype' field of the TAudioInfo
       * structure (Which can be inspected by calling the
       * 'GetAudioInfoRef()' function) or directly by calling
       * function 'GetAudioDataType()'. 
       * This function returns pointer to current audiodata. The data
       * is in the format determined by the current value of
       * 'audiodatatype' field of the TAudioInfo structure (Which can
       * be inspected by calling the 'GetAudioInfoRef()' function) or
       * directly by calling function 'GetAudioDataType()'.
       *
       * \see ConvertTo
       * \see GetAudioDataType
       * @param[out] aData   Pointer to data
       * @param[out] aSize   Size of the data
       *
       * @return                Size of audiodata in Bytes.
       */
      void GetAudioData(unsigned char **aData, unsigned int *aSize); 
    private:
      // Variables

      TAudioInfo iAudioInfo;          ///< Audioinfo for audio.
      unsigned char *iAudioDataPtr;   ///< Pointer to beginning of data.
      unsigned int iSize;             ///< Size of data in bytes.
      bool iIsOwnedBuffer;             ///< Flag to determine whether the buffer is owned.


    };
  }


}
#endif
